Skip to content

feat: Add CLI#208

Open
TheTrueAI wants to merge 2 commits intoInfluxCommunity:mainfrom
TheTrueAI:add-cli
Open

feat: Add CLI#208
TheTrueAI wants to merge 2 commits intoInfluxCommunity:mainfrom
TheTrueAI:add-cli

Conversation

@TheTrueAI
Copy link
Copy Markdown
Contributor

@TheTrueAI TheTrueAI commented Apr 20, 2026

Proposed Changes

Developers and AI tooling need a simple, scriptable query command for fast feedback during development. Existing community Python CLI seems unmaintained and not aligned with current behavior. So this PR introduces the following:

  • Adds a new influx3 query CLI path for read/query workflows.
  • Supports SQL and InfluxQL queries with JSON, JSONL, CSV, and pretty output formats.
  • Adds module entrypoint support so the CLI can also be run through python -m influxdb_client_3.
  • Fixes Windows-specific PEM newline handling for Flight query TLS root certificates.

Checklist

  • CHANGELOG.md updated
  • Rebased/mergeable
  • A test has been added if appropriate
  • Tests pass
  • Commit messages are conventional
  • Sign CLA (if not already signed)

Add a new query CLI to support quick read/debug workflows from terminal and AI agents.
- add influx3 query with json, jsonl, csv, and pretty output
- add module execution path via python -m influxdb_client_3
- wire console entry point in setup
- add CLI tests
@TheTrueAI TheTrueAI changed the title Add CLI feat: Add CLI Apr 20, 2026
Copy link
Copy Markdown
Member

@bednar bednar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TheTrueAI thanks for the PR. There is already an existing CLI tool: https://docs.influxdata.com/influxdb3/core/reference/cli/influxdb3/. What’s the reason for creating a new one in the Python v3 client?

@TheTrueAI
Copy link
Copy Markdown
Contributor Author

Good point — the official influxdb3 query CLI does cover the same query functionality. My motivation was zero-install in Python environments: pip install influxdb3-python gives you the CLI inside the venv with no separate binary needed. This is useful for Python-centric CI and AI agent workflows where adding system binaries is friction.

Happy to scope this down or close if you feel the overlap isn't justified.

@bednar
Copy link
Copy Markdown
Member

bednar commented Apr 22, 2026

Good point — the official influxdb3 query CLI does cover the same query functionality. My motivation was zero-install in Python environments: pip install influxdb3-python gives you the CLI inside the venv with no separate binary needed. This is useful for Python-centric CI and AI agent workflows where adding system binaries is friction.

Happy to scope this down or close if you feel the overlap isn't justified.

Thanks for explanation, every PR is welcome so we will be happy to review your code. Thanks again for your contribution.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a first-party, scriptable influx3 query CLI for executing SQL/InfluxQL queries against InfluxDB 3, and adds a small Windows-focused TLS root cert compatibility fix for Flight query PEM loading.

Changes:

  • Add influx3 console script + python -m influxdb_client_3 module entrypoint for query workflows.
  • Implement query execution + output formatting (JSON/JSONL/CSV/pretty), config/env precedence, and basic error handling.
  • Normalize PEM certificate line endings when reading Flight query root certs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
influxdb_client_3/cli.py New CLI implementation for influx3 query including formatting, env precedence, and output handling.
influxdb_client_3/__main__.py Enables python -m influxdb_client_3 CLI execution.
setup.py Adds console_scripts entry point for influx3.
tests/test_cli.py Adds unit tests for CLI parsing and core query execution paths.
influxdb_client_3/query/query_api.py Normalizes PEM line endings when reading root certificates.
README.md Documents CLI usage, formats, and configuration precedence.
CHANGELOG.md Adds feature + bug-fix entries for the CLI and PEM normalization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread influxdb_client_3/cli.py
Comment on lines +153 to +161
with InfluxDBClient3(host=host, database=database, token=token, **query_kwargs) as client:
table = client.query(
query=query,
language=args.language,
mode="all",
database=database,
)

payload = _ensure_trailing_nl(_format_table(table, args.output_format))
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI forces mode="all" and then converts the full pa.Table to a Python list (table.to_pylist()), which loads the entire result set into memory before formatting. This can be a major memory/latency issue for large queries, especially for JSONL/CSV where streaming would be feasible. Consider adding a streaming mode (e.g., using mode="chunk"/"reader" and writing batches incrementally) or at least documenting/guarding against very large result sets.

Copilot uses AI. Check for mistakes.
Comment thread influxdb_client_3/cli.py
Comment on lines +160 to +166

payload = _ensure_trailing_nl(_format_table(table, args.output_format))
if args.output_file_path:
with open(args.output_file_path, "w", encoding="utf-8", newline="") as file_handle:
file_handle.write(payload)
else:
stdout.write(payload)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New CLI behaviors aren’t fully covered by tests yet: there are no assertions for CSV/pretty formatting, and the --output file-write branch isn’t exercised. Adding tests for these paths would help catch platform/newline differences (CSV) and ensure file output works as intended.

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +66
certs = certs_file.read()
# Normalize PEM line endings so behavior is stable across platforms.
return certs.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change normalizes PEM line endings, but there’s no test ensuring CRLF/CR-only PEM files are normalized to LF. Since tests/test_query.py already asserts certificate loading behavior, it would be good to add a case that writes a cert file with \r\n (and/or \r) and verifies tls_root_certs matches the LF-normalized content.

Copilot uses AI. Check for mistakes.
Comment thread tests/test_cli.py
Comment on lines +134 to +137
with patch("influxdb_client_3.cli.sys.stdout", new=io.StringIO()), patch(
"influxdb_client_3.cli.sys.stderr", new=io.StringIO()
) as stderr:
rc = main(["query", "SELECT 1"])
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_main_returns_1_when_database_missing calls main() without isolating os.environ. If INFLUXDB3_DATABASE_NAME/INFLUX_DATABASE is set in the test runner environment (e.g., CI), this test will become flaky and may pass when it should fail. Patch os.environ (e.g., @patch.dict('os.environ', {}, clear=True) or at least clear the relevant keys) for the duration of this test to make it deterministic.

Suggested change
with patch("influxdb_client_3.cli.sys.stdout", new=io.StringIO()), patch(
"influxdb_client_3.cli.sys.stderr", new=io.StringIO()
) as stderr:
rc = main(["query", "SELECT 1"])
with patch.dict("os.environ", {}, clear=True):
with patch("influxdb_client_3.cli.sys.stdout", new=io.StringIO()), patch(
"influxdb_client_3.cli.sys.stderr", new=io.StringIO()
) as stderr:
rc = main(["query", "SELECT 1"])

Copilot uses AI. Check for mistakes.
Comment thread influxdb_client_3/cli.py
Comment on lines +149 to +152
query_kwargs = {}
if args.query_timeout is not None:
query_kwargs["query_timeout"] = args.query_timeout

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--query-timeout accepts any integer, including negative values, and the CLI forwards it directly into the client options. A negative timeout is invalid and will likely cause confusing downstream errors. Validate args.query_timeout >= 0 and return a clear CLI error when it’s negative.

Copilot uses AI. Check for mistakes.
Comment thread influxdb_client_3/cli.py
Comment on lines +70 to +72
def _rows_to_jsonl(rows, fieldnames):
return "\n".join(json.dumps(row, default=str) for row in rows)

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For jsonl output with zero rows, _rows_to_jsonl returns an empty string and _ensure_trailing_nl turns that into a single blank line ("\n"). For JSONL, empty results should typically produce no output (or at least avoid emitting a spurious empty record line). Consider special-casing empty rows for JSONL (or adjusting _ensure_trailing_nl to not add a newline for empty payloads).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants